/**
 * Copyright (c) 2015-2030 by Beijing Yanlight Co., Ltd.
 * All rights reserved.
 */
package com.yanlight.app.controller;

import com.yanlight.Constants;
import com.yanlight.app.response.CompanyNameResponse;
import com.yanlight.app.response.PaycodeVerifyResponse;
import com.yanlight.app.service.AdCountService;
import com.yanlight.app.service.CompanyService;
import com.yanlight.app.service.PayService;
import com.yanlight.app.service.PaycodeService;
import com.yanlight.support.pay.PayFactory;
import com.yanlight.type.OrderSceneType;
import com.yanlight.util.CookieUtil;
import com.yanlight.util.JedisKeyUtil;
import com.yanlight.util.JedisUtil;
import com.yanlight.util.LogUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;

/**
 * @author haolw
 * @time 2017/08/30
 */
@Controller
public class PayController extends BaseController {
    private final String PAY_CODE_KEY = "paycode";
    private final String SCENE_TYPE = "sceneType";
    private final String OPERATION_ID = "operationId";
    @Autowired
    private PaycodeService paycodeService;
    @Autowired
    private CompanyService companyService;

    @Autowired
    private AdCountService adCountService;

    @GetMapping("/pay/{paycode}")
    public ModelAndView pay(HttpServletRequest request, @PathVariable String paycode, ModelAndView model) {

        boolean processPay = true;
        model.setViewName(Constants.NO_SERVICE_VIEW);
        model.addObject(PAY_CODE_KEY, paycode);
        model.addObject(SCENE_TYPE, OrderSceneType.OFF_LINE.getType());

        String dynamicCode = StringUtils.substringBetween(paycode, Constants.DOLLAR);
        if (dynamicCode != null) {
            processPay = processBranchDynamic(dynamicCode, model);
        }
        if (processPay) {
            verifyPay(model, request);
        }
        return model;
    }

    @GetMapping("/testPay")
    @ResponseBody
    public ModelAndView testPay(ModelAndView model) {
        model.setViewName(Constants.TEST_PAY);
        return model;
    }

    @GetMapping("/actives")
    public ModelAndView actives(ModelAndView model) {
        model.setViewName(Constants.TEST_PAY);
        return model;
    }

    /**
     * 消费者使用微信、支付宝扫业务员B端APP上的动态支付码
     */
    private boolean processBranchDynamic(String code, ModelAndView model) {
        String dynamicCode = StringUtils.substringBefore(code, Constants.AT);
        String operationId = StringUtils.substringAfter(code, Constants.AT);
        String dynamicPayKey = JedisKeyUtil.getDynamicPayCode(dynamicCode);
        if (JedisUtil.exists(dynamicPayKey)) {
            String paycode = JedisUtil.get(dynamicPayKey);
            model.addObject(PAY_CODE_KEY, paycode);
            model.addObject(OPERATION_ID, operationId);
            model.addObject(SCENE_TYPE, OrderSceneType.USER_SCAN_DYNAMIC.getType());
            return true;
        } else {
            return false;
        }
    }

    private void verifyPay(ModelAndView model, HttpServletRequest request) {
        String paycode = String.valueOf(model.getModel().get(PAY_CODE_KEY));
        PaycodeVerifyResponse verifyResponse = paycodeService.verify(paycode);
        Integer companyId = verifyResponse.getCompanyId();
        if (companyId != null) {
            if (companyService.checkAvailable(companyId)) {
                PayService payService = PayFactory.getPayService(request);
                if (payService != null && payService.checkConfig(companyId)) {
                    Integer binderId = verifyResponse.getBinderId();
                    CompanyNameResponse nameResponse = companyService.findName(companyId);
                    nameResponse.setCodeValue(paycode);

                    LogUtil.showLog(nameResponse);

                    String payView = PayFactory.getPayView(request);
                    model.setViewName(payView);

                    String userAuthId = null;
                    Integer payType = 0;
                    if (payView.equals(Constants.ALIPAY_VIEW)) {
                        payType = 2;
                        userAuthId = CookieUtil.getValue(request, Constants.ALIPAY_USER_ID);
                    } else if (payView.equals(Constants.WXPAY_VIEW)) {
                        payType = 1;
                        userAuthId = CookieUtil.getValue(request, Constants.WX_OPENID);
                    }

                    nameResponse.setUserAuthId(userAuthId);
                    boolean response = adCountService.isShowRedPacket(payType, userAuthId, Long.parseLong(nameResponse.getCompanyId()), nameResponse.getCodeValue());
                    nameResponse.setShowRedPacket(response);

                    model.addAllObjects(nameResponse.getModelMap());
                    if (binderId != null) {
                        model.addObject(OPERATION_ID, binderId);
                        model.addObject(SCENE_TYPE, OrderSceneType.USER_SCAN_BIND_STATIC.getType());
                    }
                }
            }
        } else {
            model.setViewName(Constants.NO_BIND_VIEW);
        }
    }
}
